package com.cheetah.cloud2020.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cheetah.cloud2020.entity.SystemJob;
import com.cheetah.cloud2020.mapper.SystemJobMapper;
import com.cheetah.cloud2020.service.RibbonJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

@Configuration
@EnableScheduling
public class SpringTaskMgr implements SchedulingConfigurer {
    private static TaskScheduler taskScheduler;
    private static ScheduledTaskRegistrar registrar;
    private static Map<Serializable, ScheduledTask> taskMap = new ConcurrentHashMap<>();
    @Autowired
    @Lazy
    private SystemJobMapper systemJobMapper;
    @Autowired
    private RibbonJobService ribbonJobService;

    @Bean
    public Executor threadPool() {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(8);
        taskScheduler = new ConcurrentTaskScheduler(pool);
        return pool;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        SpringTaskMgr.registrar = scheduledTaskRegistrar;
        this.systemJobMapper.selectList(
                new QueryWrapper<SystemJob>().eq("state", 1))
                .forEach(item -> {
            ribbonJobService.addCron(item);
        });
    }

    /**
     * 添加任务，每次都先取消任务，可以用于更新任务
     * @param id
     * @param task
     * @param cron
     */
    public static void addCronTask(Serializable id, Runnable task, String cron) {
        cancel(id);
        taskMap.put(id, registrar.scheduleCronTask(new CronTask(task, cron)));
    }

    public static void cancel(Serializable id) {
        ScheduledTask task = taskMap.remove(id);
        if (task != null) {
            task.cancel();
        }
    }

}
